<?php

namespace api\modules\guest\controllers;

use api\models\db\ApiUsers;
use common\components\fast_api\Controller;
use common\datas\Enums;
use common\models\db\Files;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh;
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin;
use Endroid\QrCode\Writer\PngWriter;
use yii\base\Exception;

class PubController extends Controller
{
    /**
     * 测试
     * @desc api测试
     * @param string $test
     * @param int $isError 1是2否
     * @param int $isExpection 1是2否
     * @return array
     * @return string test
     */
    public function actionTest($test, $isError = Enums::NO, $isExpection = Enums::NO)
    {
        if ($isExpection == Enums::YES) {
            throw new Exception("测试");
        }
        if ($isError == Enums::YES) {
            return $this->apiError("测试");
        }
        $data = [
            'test' => $test,
        ];
        return $this->apiSuccess($data);
    }

    /**
     * 获取令牌
     * @desc 测试环境
     * @return array
     * @return string token
     * @return string key
     */
    public function actionAuthData()
    {
        if (!YII_ENV_DEV) {
            return $this->apiError("只能在测试环境下获取");
        }
        $apiUser = ApiUsers::find()->one();
        if (!$apiUser) {
            $apiUser = new ApiUsers();
            $apiUser->generateToken();
            if (!$apiUser->save()) {
                return $this->apiError("生成失败");
            }
        }
        return $this->apiSuccess([
            'token' => $apiUser->token,
            'key' => $apiUser->key,
        ]);
    }

    /**
     * 生成图片
     * @param string $w
     * @param string $h
     * @param string $fontSize
     * @return void
     */
    public function actionGd($w = 300, $h = null, $fontSize = 1, $fontStr = null)
    {
        if (!$h) {
            $h = $w;
        }
        if (!$fontStr) {
            $fontStr = "{$w}x{$h}";
        }
        $fontStr = mb_convert_encoding($fontStr, 'UTF-8', 'auto');
//        $fontPath = \Yii::getAlias('@common/fonts/TEMPSITC.TTF');
        $fontPath = \Yii::getAlias('@common/fonts/SourceHanSansHW-VF.ttf');
        // 检查字体文件是否存在
        if (!file_exists($fontPath)) {
            die("Error: Font file not found.");
        }

        // 创建一个 wxh 像素的图像资源
        $image = imagecreatetruecolor($w, $h);
        // 设置背景颜色
        $white = imagecolorallocate($image, 100, 100, 100);
        // 填充背景
        imagefill($image, 0, 0, $white);
        // 设置文字颜色
        $black = imagecolorallocate($image, 250, 250, 250);
        // 添加文字（使用 GD 内置字体）
        // 第一个参数是图像资源，第二个参数是字体大小，第三个参数是文本颜色，第四个参数是文本内容
        // 第五个参数是文本在图像上的位置（x, y），这里设置为图像中心
        $textWidth = imagefontwidth($fontSize)*strlen($fontStr); // 获取字体宽度
        $textHeight = imagefontheight($fontSize); // 获取字体高度
        // 使用 imagettfbbox 获取文本的尺寸
//        $bbox = imagettfbbox($fontSize, 0, $fontPath, $fontStr);
        // 计算文本的宽度
//        $textWidth = $bbox[2] - $bbox[0];
        // 计算文本的高度
//        $textHeight = abs($bbox[1] - $bbox[7]);
        /*$x = ($w - $textWidth) / 2; // 计算文本水平位置
        $y = ($h - $textHeight) / 2; // 计算文本垂直位置
        imagestring($image, $fontSize, $x, $y, $fontStr, $black);*/
//        Tools::yiiLog("{$w}x{$h} {$textWidth}x{$textHeight} {$x}x{$y}");
        // 中文字体可能会出现乱码的解决方式
        /**
         * 计算文本的边界框
         * $fontBox[0] 和 $fontBox[1]：左下角坐标。
         * $fontBox[2] 和 $fontBox[3]：右下角坐标。
         * $fontBox[4] 和 $fontBox[5]：左上角坐标。
         * $fontBox[6] 和 $fontBox[7]：右上角坐标。
         */
        $fontBox = imagettfbbox($fontSize, 0, $fontPath, $fontStr);
        // 计算文本宽度
        $textWidth = $fontBox[2] - $fontBox[0];
        // 计算文本高度
        $textHeight = $fontBox[7] - $fontBox[1];
        $x = ($w - $textWidth) / 2; // 计算文本水平位置
        $y = ($h - $textHeight) / 2; // 计算文本垂直位置
        imagettftext($image, $fontSize, 0, $x, $y, $black, $fontPath, $fontStr);
        // 输出图像
        header('Content-Type: image/jpeg');
//        \Yii::$app->response->format = Response::FORMAT_HTML;
//        \Yii::$app->response->headers->set('Content-Type', 'image/png');
        imagepng($image);
        // 销毁图像资源
        imagedestroy($image);
        exit;
    }

    /**
     * 本地缩略图
     * @desc url显示缩略图 需要存在本地的图片文件
     * @param string $src 图片url
     * @return string | array
     */
    public function actionLocalThumbImage($src)
    {
        $info = parse_url($src);
        $path = $info['path'];
        if (substr($path, 0, 9) === '/storage/') {
            $root = \Yii::getAlias('@storage_root').str_replace('/storage/', '/', $path);
            if (file_exists($root)) {
                $file = $root;
            }
        } else {
            if (substr($path, 0, 15) === '/static/images/') {
                $root = \Yii::getAlias('@static_root').str_replace('/static/images/', '/images/', $path);
                if (file_exists($root)) {
                    $file = $root;
                }
            } else {
                return $this->apiError("文件不存在");
            }
        }

        $info = pathinfo($file);
        $ext = $info['extension'];

        // 读取原始图片
        switch ($ext) {
            case "jpg":
            case "jpeg":
                $srcImg = imagecreatefromjpeg($src);
                break;
            case "png":
                $srcImg = imagecreatefrompng($src);
                break;
            case "webp":
                $srcImg = imagecreatefromwebp($src);
                break;
            case "bmp":
                $srcImg = imagecreatefrombmp($src);
                break;
            case "wbmp":
                $srcImg = imagecreatefromwbmp($src);
                break;
            case "gif":
                $srcImg = imagecreatefromgif($src);
                break;
            default:
                $src = \Yii::getAlias('@static_aburl/images/404.jpeg');
                header('Content-Type: image/jpeg');
                readfile($src);exit;
        }
        $mimeType = \Yii::$app->wMimeTypes->getMimeType($ext);
        header('Content-Type: '.$mimeType);

        // 缩略图最大宽度和高度
        $maxWidth = 400;
        $maxHeight = 400;

        // 计算缩略图大小
        $srcWidth = imagesx($srcImg);
        $srcHeight = imagesy($srcImg);
        $scale = min($maxWidth / $srcWidth, $maxHeight / $srcHeight);
        $newWidth = round($srcWidth * $scale);
        $newHeight = round($srcHeight * $scale);

        // 创建新的图像资源
        $newImg = imagecreatetruecolor($newWidth, $newHeight);

        // 将原始图片复制到新的图像资源中，并缩小
        imagecopyresampled($newImg, $srcImg, 0, 0, 0, 0, $newWidth, $newHeight, $srcWidth, $srcHeight);

        // 保存新的图像资源
        imagejpeg($newImg);
        exit;
    }

    /**
     * 下载文件
     * @desc 需要本地存在数据
     * @param $userFileSrc
     * @return void
     */
    public function actionDownloadFile($userFileSrc)
    {
        $userFile = Files::findOne(['filename' => $userFileSrc]);
        if (!$userFile) {
            exit('文件未找到');
        }
        $fileRoot = $userFile->root;
        if (!file_exists($fileRoot)) {
            exit('文件不存在');
        }
        // 获取文件名
        $filename = basename($fileRoot);
        // 清理文件名，防止特殊字符导致问题
        $filename = rawurldecode($filename);
        // 发送相应的头信息，告诉浏览器要下载文件
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'. $filename. '"');
        header('Content-Length: '. filesize($fileRoot));
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        // 输出文件内容
        readfile($fileRoot);
        exit;
    }

    /**
     * 生成二维码
     * @desc 生成二维码
     * @param string $text 文本
     * @return void
     */
    public function actionQrcode($text)
    {
        $result = Builder::create()
            ->writer(new PngWriter())
            ->writerOptions([])
            ->data($text)
            ->encoding(new Encoding('UTF-8'))
            ->errorCorrectionLevel(new ErrorCorrectionLevelHigh())
            ->size(480)
            ->margin(10)
            ->roundBlockSizeMode(new RoundBlockSizeModeMargin())
            ->logoPath(\Yii::getAlias('@wroot/favicon.png'))
//            ->labelText('label')
//            ->labelFont(new NotoSans(20))
//            ->labelAlignment(new LabelAlignmentCenter())
            ->validateResult(false)
            ->build();
        // Directly output the QR code
        header('Content-Type: '.$result->getMimeType());
        echo $result->getString();
        exit;
    }
}
